package coreBiz

import (
	"crypto/md5"
	"crypto/rand"
	"crypto/rc4"
	"crypto/sha1"
	"encoding/base64"
	"encoding/hex"
	"fmt"
	math_rand "math/rand"
	"strings"
	"time"
	"unicode"

	"github.com/spf13/cast"
)

func Lower(str string) string {
	return strings.ToLower(str)
}

func Upper(str string) string {
	return strings.ToUpper(str)
}

func IsEmpty(str string) bool {
	return strings.TrimSpace(str) == ""
}

func IsZero(i int) bool {
	return i == 0
}

// Md5 字符串转md5 将编码转换为字符串
func Md5(data string) string {
	return fmt.Sprintf("%x", md5.Sum([]byte(data)))
}

// Md5Bytes md5 小写
func Md5Bytes(data []byte) string {
	return fmt.Sprintf("%x", md5.Sum(data))
}

// UcFirst 首字母大写
func UcFirst(s string) string {
	if s == "" {
		return ""
	}
	runes := []rune(s)
	runes[0] = unicode.ToUpper(runes[0])
	return string(runes)
}

// Rc4Encrypt 加密 urlencoded base64
func Rc4Encrypt(key, plaintext []byte) (string, error) {
	cipher, err := rc4.NewCipher(key)
	if err != nil {
		return "", err
	}
	dst := make([]byte, len(plaintext))
	cipher.XORKeyStream(dst, plaintext)

	return base64.StdEncoding.EncodeToString(dst), nil
}

// Rc4Decrypt 解密密文（已 base64 编码）
// key: 密钥
// cipherTextBase64: base64 编码后的密文
func Rc4Decrypt(key []byte, cipherTextBase64 string) (string, error) {
	// base64 解码
	cipherBytes, err := base64.StdEncoding.DecodeString(cipherTextBase64)
	if err != nil {
		return "", err
	}

	// 创建 RC4 cipher
	cipher, err := rc4.NewCipher(key)
	if err != nil {
		return "", err
	}

	// 解密（RC4 解密同加密过程）
	plainBytes := make([]byte, len(cipherBytes))
	cipher.XORKeyStream(plainBytes, cipherBytes)

	return string(plainBytes), nil
}

func Sha1(data string) string {
	// 计算SHA1
	h := sha1.New()
	h.Write([]byte(data))
	return fmt.Sprintf("%x", h.Sum(nil))
}

func Bin2Hex(data []byte) string {
	return hex.EncodeToString(data)
}

func Hex2Bin(hexStr string) ([]byte, error) {
	return hex.DecodeString(hexStr)
}

// GetSex 根据身份证号获取性别 0-未知 1-男 2-女
func GetSex(idcard string) int {
	var sexIndex, sex int

	if len(idcard) == 15 {
		//根据最后一位判断性别,奇男偶女=>1为男 2为女
		sexIndex = cast.ToInt(idcard[14:])
	} else if len(idcard) == 18 {
		//根据最后倒数第二位判断性别
		sexIndex = cast.ToInt(idcard[16:17])
	} else {
		return 0
	}

	if sexIndex%2 == 0 {
		sex = 2
	} else {
		sex = 1
	}
	return sex
}

// GetYears 根据身份证号获取年代 空:未知 正常:如1950
func GetYears(idcard string) (years string) {
	if len(idcard) == 15 {
		years = "19" + string(idcard[6:7]) + "0"
	} else if len(idcard) == 18 {
		years = string(idcard[6:9]) + "0"
	} else {
		years = ""
	}
	return
}

// UpdateIfChanged 如果值变了则返回true，并且赋新的值
func UpdateIfChanged[T comparable](old *T, newVal T) bool {
	if *old != newVal {
		*old = newVal
		return true
	}
	return false
}

// RemoveWhitespace 去除特殊字符
func RemoveWhitespace(input string) string {
	// 去掉空格、换行和制表符
	withoutSpace := strings.Map(func(r rune) rune {
		if unicode.IsSpace(r) {
			return -1 // 将空格、换行和制表符替换为 -1
		}
		return r
	}, input)

	return withoutSpace
}

// RandomString 生成指定长度的随机字符串（使用加密安全的随机数生成器）
func RandomString(n int) string {
	const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
	b := make([]byte, n)

	// 使用加密安全的随机数生成器
	randomBytes := make([]byte, n)
	if _, err := rand.Read(randomBytes); err != nil {
		// 如果加密随机数生成失败，回退到数学随机数
		r := math_rand.New(math_rand.NewSource(time.Now().UnixNano()))
		for i := range b {
			b[i] = letters[r.Intn(len(letters))]
		}
		return string(b)
	}

	for i := range b {
		b[i] = letters[int(randomBytes[i])%len(letters)]
	}
	return string(b)
}
